var express = require('express');
var router = express.Router();
const Category = require('../models/Category');
const SchemaDef = require('../models/SchemaDef');
var tools = require('../utils/tools')

/**
 * @swagger
 * /cmdb/categories/options:
 *   get:
 *     tags:
 *       - 分类管理
 *     summary: 分类树
 *     description: 分类树
 *     responses:
 *       200:
 *         description: 返回label、value、children标识符的属性结构。不返回没有子分类的节点
 */
router.get('/options', function (req, res, next) {
  Category.aggregate([
    {
      $match: {
        $or: [{ parent: { $exists: false } }, { parent: null }, { parent: '' }]
      }
    },
    {
      $lookup:
      {
        from: "categories",
        localField: "code",
        foreignField: "parent",
        as: "children"
      }
    }
  ], (err, docs) => {
    if (err) {
      if (err) return tools.handleError(res, err);
    }
    const data = docs.map(doc => {
      const parent = { label: doc.name, value: doc.code, id: doc._id }
      parent.children =
        doc.children.map(child => {
          return { label: child.name, value: child.code, id: child._id }
        })
      return parent
    })
    res.json({ status: 'success', data: data })
  })

});

/**
 * @swagger
 * /cmdb/categories/count/1:
 *   get:
 *     tags:
 *       - 分类管理
 *     summary: 一级分类数量
 *     description: 一级分类数量
 *     responses:
 *       200:
 *         description: 一级分类数量
 */
router.get('/count/1', async function (req, res, next) {
  var count = await Category.count({$or: [{ parent: { $exists: false } }, { parent: null }, { parent: '' }]})
  res.json({ status: 'success', data: count })
});

/**
 * @swagger
 * /cmdb/categories/count/2:
 *   get:
 *     tags:
 *       - 分类管理
 *     summary: 二级分类数量
 *     description: 二级分类数量
 *     responses:
 *       200:
 *         description: 二级分类数量
 */
router.get('/count/2', async function (req, res, next) {
  var count = await Category.count({$and: [{ parent: { $exists: true } }, { parent: {$ne: ''} }]})
  res.json({ status: 'success', data: count })
});

/**
 * @swagger
 * /cmdb/categories/page:
 *   get:
 *     tags:
 *       - 分类管理
 *     summary: 分页查询分类
 *     description: 分页查询分类，支持查询参数s_parent。如果不指定，查询所有一级分类
 *     parameters:
 *       - name: s_parent
 *         description: 父分类编码
 *         in: query
 *         required: false
 *         type: string
 *     responses:
 *       200:
 *         description: status/data结构
 */
router.get('/page', function (req, res, next) {
  var query = tools.queryResolver(req.query)
  if (query.parent) {
    query.parent = query.parent.source
  } else {
    query['$or'] = [{ parent: { $exists: false } }, { parent: null }, { parent: '' }]
  }

  Category.page(query, req.query.page, req.query.size, result => {
    return res.json({ status: 'success', data: result.docs, pageable: result.pageable })
  })
});

/**
 * @swagger
 * /cmdb/categories:
 *   post:
 *     tags:
 *       - 分类管理
 *     summary: 创建分类
 *     description: 创建分类
 *     parameters:
 *       - name: code
 *         description: 分类编码
 *         in: formData
 *         required: true
 *         type: string
 *       - name: name
 *         description: 分类名称
 *         in: formData
 *         required: true
 *         type: string
 *       - name: parent
 *         description: 父分类编码
 *         in: formData
 *         required: false
 *         type: string
 *       - name: attrs
 *         description: 属性定义（只有二级分类才能定义属性）
 *         in: formData
 *         required: false
 *         type: arrays
 *     responses:
 *       200:
 *         description: status/data结构
 */
router.post('/', async function (req, res) {
  var { parent, code, name, attrs } = req.body
  var data = { code, name }
  if (!!parent) {
    var category = await Category.findOne({ code: parent })
    if (!category) {
      return tools.handleError(res, '一级分类不存在');
    }
    data.parent = parent
    data.attrs = attrs
  }
  Category.create(data, function (err, doc) {
    if (err) return tools.handleError(res, err);
    return res.json({ status: 'success', data: doc })
  });
});

/**
 * @swagger
 * /cmdb/categories/{id}:
 *   get:
 *     tags:
 *       - 分类管理
 *     summary: 分类详情
 *     description: 分类详情
 *     parameters:
 *       - name: id
 *         description: 分类ID或分类编码
 *         in: path
 *         required: true
 *         type: string
 *     responses:
 *       200:
 *         description: status/data结构
 */
router.get('/:id', function (req, res, next) {

  var isById = tools.isValidObjectId(req.params.id)
  var query = isById ? { _id: req.params.id } : { code: req.params.id }

  Category.findOne(query)
    .exec((err, doc) => {
      if (err) return tools.handleError(res, err);
      return res.json({ status: 'success', data: doc })
    })
});

/**
 * @swagger
 *
 * /cmdb/categories/{id}:
 *   delete:
 *     tags:
 *       - 分类管理
 *     summary: 删除分类
 *     description: 删除分类
 *     parameters:
 *       - name: id
 *         description: 分类ID或分类编码
 *         in: path
 *         required: true
 *         type: string
 *     responses:
 *       200:
 *         description: 分类不存在、分类存在子分类、分类下存在模型定义，status=failure
 */
router.delete('/:id', async function (req, res, next) {

  var isById = tools.isValidObjectId(req.params.id)
  var query = isById ? { _id: req.params.id } : { code: req.params.id }
  var category = await Category.findOne(query)
  if (!category) {
    return tools.handleError(res, '分类不存在');
  }

  const childCount = await Category.count({ parent: category.code })
  if (childCount > 0) {
    return tools.handleError(res, '请先删除子分类');
  }

  const shcemaCount = await SchemaDef.count({ category: category.code })
  if (shcemaCount > 0) {
    return tools.handleError(res, '请先删除分类模型');
  }

  Category.findOneAndDelete(query, function (err) {
    if (err) return tools.handleError(res, err);
    return res.json({ status: 'success' })
  });
});

/**
 * @swagger
 * /cmdb/categories/{id}:
 *   put:
 *     tags:
 *       - 分类管理
 *     summary: 更新分类
 *     description: 更新分类
 *     parameters:
 *       - name: id
 *         description: 分类ID或分类编码
 *         in: path
 *         required: true
 *         type: string
 *       - name: code
 *         description: 分类编码
 *         in: formData
 *         required: true
 *         type: string
 *       - name: name
 *         description: 分类名称
 *         in: formData
 *         required: true
 *         type: string
 *       - name: parent
 *         description: 父分类编码
 *         in: formData
 *         required: false
 *         type: string
 *       - name: attrs
 *         description: 属性定义（只有二级分类才能定义属性）
 *         in: formData
 *         required: false
 *         type: arrays
 *     responses:
 *       200:
 *         description: 分类不存在，status=failure
 */
router.put('/:id', async function (req, res, next) {

  var isById = tools.isValidObjectId(req.params.id)
  var query = isById ? { _id: req.params.id } : { code: req.params.id }
  var beforeUpdate = await Category.findOne(query)
  if (!beforeUpdate) {
    return tools.handleError(res, '分类不存在');
  }

  var { code, name, parent, attrs } = req.body
  if (!attrs) attrs = []
  var data = {
    code,
    name
  }

  if (!isTopCategory(beforeUpdate)) {
    data.parent = parent
    data.attrs = attrs
  }

  var afterUpdate = await Category.findOneAndUpdate(query, { $set: data }, { new: true });

  if (isTopCategory(beforeUpdate)) {
    await Category.updateMany({ parent: beforeUpdate.code }, { $set: { parent: afterUpdate.code } })
  } else {
    await SchemaDef.updateMany({ category: beforeUpdate.code }, { $set: { category: afterUpdate.code } })
  }

  res.json({ status: 'success', data: afterUpdate })
});

function isTopCategory (doc) {
  return !doc.parent
}

module.exports = router;
